package Routine

import (
	"fmt"
	"sync"
	"time"
)

type workerEngine struct {
	done  chan int64
	wg    sync.WaitGroup
	close bool
}

func NewWorkerEngine() *workerEngine {
	ptr := &workerEngine{}
	ptr.close = false
	ptr.done = make(chan int64)

	return ptr
}

func (e *workerEngine) worker(id int64, done chan<- int64, worker func(id int64), wg *sync.WaitGroup) {
	defer wg.Done()

	worker(id)

	// 通知主线程已完成
	select {
	case done <- id:
		// 正常发送
	case <-time.After(1 * time.Second):
		// 防止主线程已关闭通道
		fmt.Errorf("Worker %d: timeout sending done notification\n", id)
	}
}

func (e *workerEngine) Run(workerCount int64, worker func(id int64)) {
	// 初始创建N个worker
	for i := int64(1); i <= workerCount; i++ {
		e.wg.Add(1)
		go e.worker(i, e.done, worker, &e.wg)
	}

	// 用于生成新的worker ID
	nextID := workerCount + 1

	// 监听完成通知并创建新的worker
	go func() {
		for id := range e.done {
			fmt.Errorf("工作协程id= %d已经完成，创建新的协程\n", id)
			e.wg.Add(1)
			go e.worker(nextID, e.done, worker, &e.wg)
			nextID++

			// 检查：是否需要退出
			if e.close {
				return
			}
		}
	}()
}

func (e *workerEngine) Close() {
	e.close = true

	// 使用单独的 goroutine 来关闭通道
	go func() {
		e.wg.Wait()
		close(e.done)
	}()
}
